#pragma once
#include <iostream>
#include <string>
#include <functional>
#include "InetAddr.hpp"
using namespace std;

class Reactor;
class Connection;
// 回调
using func_t = function<void(Connection *)>;

// 链接类---以链接为整体看待
// 每个fd都当成每个链接对象
class Connection
{
public:
    Connection(int sock)
        : _sock(sock),
          _R(nullptr)
    {
    }
    // 获取sockfd
    int Sockfd()
    {
        return _sock;
    }
    // 获取关心事件
    uint32_t Events()
    {
        return _events;
    }
    // 设置sockfd关心的事件集合
    void SetEvents(int events)
    {
        _events = events;
    }
    // 注册各种方法，对于此sock
    void Register(func_t recver, func_t sender, func_t excepter)
    {
        _recver = recver;
        _sender = sender;
        _excepter = excepter;
    }
    // 注册TcpServer *_self属性
    void SetSelf(Reactor *R)
    {
        _R = R;
    }
    ~Connection() {}
    // 将读取到的信息添加到输入缓冲区中
    void AppendInBuffer(const string &buff)
    {
        _inbuffer += buff; // 追加
    }
    // 将要发送的信息添加至输出缓冲区中
    void AppendOutBuffer(const string &buff)
    {
        _outbuffer += buff;
    }
    bool OutbufferEmpty()
    {
        return _outbuffer.empty();
    }
    string &Inbuffer()
    {
        return _inbuffer;
    }
    string &Outbuffer()
    {
        return _outbuffer;
    }
    // 从发送缓冲区中移除n个字节数据
    void OutbufferRemove(int n)
    {
        _outbuffer.erase(0, n);
    }
    void Close()
    {
        if (_sock >= 0)
        {
            close(_sock);
        }
    }
    // 检查写事件是否被关心
    bool IsEnableWrite()
    {
        if (_events & EPOLLOUT > 0)
        {
            return true;
        }
        return false;
    }

private:
    int _sock;         // 套接字
    string _inbuffer;  // 输入缓冲区-接收缓冲区-外设->内核
    string _outbuffer; // 输出缓冲区-发送缓冲区-内核->外设

    InetAddr _addr; // 客户端的网络信息

    uint32_t _events; // 事件集合，Connection对象中，sock关心的事件集合

public:
    // 方法集合
    func_t _recver;   // 读-指针
    func_t _sender;   // 写-指针
    func_t _excepter; // 异常-指针
    Reactor *_R;      // 链接对象回指TcpServer对象
};